using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace FGUIDReplace
{
    public class GUIDReplace
    {
        /// <summary> 搜索包含 </summary>
       /// <param name="tree">树图</param>
       /// <param name="dirs">文件夹列表</param>
       /// <param name="oldObj">旧资源</param>
        public static void SearchInclude(ReplaceTreeView tree, List<DefaultAsset> dirs, Object oldObj)
        {
            var complete = true;

            tree.Clear();
            AssetDatabase.SaveAssets();

            var oldObjectPath = AssetDatabase.GetAssetPath(oldObj);
            // var oldGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(oldObject));
            AssetDatabase.TryGetGUIDAndLocalFileIdentifier(oldObj, out var oldGuid, out long _);

            for (var i = 0; i < dirs.Count; i++)
            {
                var path = AssetDatabase.GetAssetPath(dirs[i]);
                if (string.IsNullOrEmpty(path))
                    continue;

                var filePaths = GetDirectoryAllFile(path);

                for (int j = 0; j < filePaths.Length; j++)
                {
                    // 排除自身 .meta
                    if (filePaths[j] == $"{oldObjectPath}.meta")
                        continue;

                    var content = File.ReadAllText(filePaths[j]);
                    if (Regex.IsMatch(content, oldGuid))
                        tree.AddPath(filePaths[j]);

                    var progress = (i * filePaths.Length + j + 1.0f) / (dirs.Count * filePaths.Length);
                    if (EditorUtility.DisplayCancelableProgressBar("查找引用...", filePaths[j], progress))
                    {
                        complete = false;
                        break;
                    }
                }

                if (complete == false)
                {
                    EditorUtility.ClearProgressBar();
                    tree.Clear();
                    break;
                }
            }

            EditorUtility.ClearProgressBar();
            tree.RefreshReload();
        }

        /// <summary> 替换 </summary>
        /// <param name="tree">树图</param>
        /// <param name="oldObj">旧资源</param>
        /// <param name="newObj">新资源</param>
        public static void Replace(ReplaceTreeView tree, Object oldObj, Object newObj)
        {
            // var oldGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(oldObj));
            // var newGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(newObj));
            AssetDatabase.TryGetGUIDAndLocalFileIdentifier(oldObj, out var oldGuid, out long _);
            AssetDatabase.TryGetGUIDAndLocalFileIdentifier(newObj, out var newGuid, out long _);

            for (var i = 0; i < tree.GetRows().Count; i++)
            {
                var path = tree.GetRows()[i].displayName;

                var content = File.ReadAllText(path);
                if (Regex.IsMatch(content, oldGuid))
                {
                    content = content.Replace(oldGuid, newGuid);
                    File.WriteAllText(path, content);
                }

                if (EditorUtility.DisplayCancelableProgressBar("美术工具箱", $"替换：{path}", i * 1.0f / tree.GetRows().Count))
                {
                    EditorUtility.ClearProgressBar();
                    return;
                }
            }

            EditorUtility.ClearProgressBar();

            tree.Clear();
            AssetDatabase.Refresh();
        }

        /// <summary> 获取文件夹所有文件 </summary>
        static string[] GetDirectoryAllFile(string path)
        {
            // path     搜索路径
            // return   返回所有文件

            var tempPath = new List<string>();

            GetAllPath(path, tempPath);

            return tempPath.Select(item => item.Replace("\\", "/")).ToArray();

            static void GetAllPath(string path, List<string> allPath)
            {
                var dirs = Directory.GetDirectories(path);

                // 对每个目录执行相同的操作
                foreach (var dir in dirs)
                    GetAllPath(dir, allPath);

                var files = Directory.GetFiles(path);
                allPath.AddRange(files);
            }
        }
    }
}